package com.test2.opencv;

import com.test2.opencv.util.Mat2BufImg;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.MouseInfo;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class TestOpencv3 {

   private double nndrRatio = 0.8D;

    public static void main(String[] args) throws IOException, AWTException {
        nu.pattern.OpenCV.loadShared();
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        new TestOpencv3().getAllRectangualObj(Paths.get("D:\\123.jpg"),10,10,0,0,300);
    }

    public List<Rect> getAllRectangualObj(Path imagePath, int sizeW, int sizeH, int thresholdStrength, int thresholdWeakness, int boundFilter) throws AWTException, IOException {
        long start = System.currentTimeMillis();
        //opencv环境检查
        environmentalInspection();
        Robot robot=new Robot();
        Toolkit toolkit= Toolkit.getDefaultToolkit();
        Dimension d = toolkit.getScreenSize();
        Rectangle screenRect = new Rectangle(d);

        int x = MouseInfo.getPointerInfo().getLocation().x;
        int y = MouseInfo.getPointerInfo().getLocation().y;
        Point point = new Point(x,y);
        BufferedImage bufferedImage =  robot.createScreenCapture(screenRect);
        ImageIO.write(bufferedImage,"jpg",new File("d:\\test2.jpg"));
        Mat imread = Imgcodecs.imread("d:\\test2.jpg");
        //Mat imread =  Mat2BufImg.BufImg2Mat(bufferedImage,BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
        //图片预处理
        Mat desc = imagePreprocessing(imread,sizeW,sizeH);
        HighGui.imshow("预处理", desc);
        //检测边缘
        Mat temp = new Mat();//边缘检测结果
        Imgproc.Canny(desc, temp,thresholdStrength,thresholdWeakness,3,false);
        List<MatOfPoint> list = new ArrayList<>();
        Mat hierarchy = new Mat();
        //查找边缘
        //查找边缘为封闭的矩形
        Imgproc.findContours(temp, list,hierarchy,Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE);
        /*
            遍历找到的矩形边缘，当边缘大小超过一定值的时候，记录找到边缘的坐标和宽高
         */
        List<Rect> rects = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {//遍历查找到的边缘
            MatOfPoint mp = list.get(i);
            double v = Imgproc.contourArea(mp);
            //获取边缘大小
            if(v > boundFilter) {
                Rect rect = Imgproc.boundingRect(mp);//边缘转化为矩形
                //if( rect.contains(point)){
                    rects.add(rect);
                //}
            }
        }
        //展示
        HighGui.imshow("原图", imread);
        HighGui.imshow("处理后", desc);
        Mat out = new Mat(imread.size(),imread.type());
        imread.copyTo(out);
        rects.forEach(rect->{
            Imgproc.rectangle(out, rect, new Scalar(0,0,255));
        });
        HighGui.imshow("边缘检测", out);
        System.out.println("use time:"+(System.currentTimeMillis() - start));
        HighGui.waitKey(0);

        return rects;
    }
    /**
     * 图片预处理
     * @param imread 图片对象
     * @param sizeW 像素点加粗宽度
     * @param sizeH 像素点加粗高度
     * @return 处理后的对象
     */
    private Mat imagePreprocessing(Mat imread,int sizeW,int sizeH) {
        Mat desc = new Mat();

        //转为灰度
        Imgproc.cvtColor(imread, desc, Imgproc.COLOR_BGR2GRAY);
        //Imgproc.GaussianBlur(desc, desc, new Size(0, 0), 3);
//        Core.addWeighted(desc, -1.5, desc, -0.5, 0, desc);
        // 拉普拉斯锐化
//        Imgproc.Laplacian(desc, desc, CvType.CV_8U);
        //Core.addWeighted(desc, 1.5, desc, -0.5, 0, desc);
        //Imgproc.equalizeHist(desc, desc);
        Imgproc.blur(desc,desc,new Size(3,3));

        // 定义膨化操作的内核（kernel）
//        Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
//        // 进行膨化处理
//        Imgproc.dilate(desc, desc, kernel);
        return desc;
    }

    /**
     * opencv 环境检查
     */
    private void environmentalInspection() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("opencv = " + Core.VERSION);
    }


}
